#ifndef G3_RES_TEXTURE_MGR_H
#define G3_RES_TEXTURE_MGR_H

#include "singleton.h"

#include "file/f_absfs.h"
#include "file/f_filehandler.h"

#include "res_texture.h"
#include "res_handle_mgr.h"
#include "tex/tex_bitmap.h"
#include "math/m_vector.h"

#include <map>
#include <set>
#include <vector>

namespace G3 {

// TODO:: Make Thread-Safe

class TEXTURE_MANAGER: public SINGLETON <TEXTURE_MANAGER>, public RESOURCE_MANAGER<TEXTURE> {
	private:
		bool lock_next_texture_bitmap;

	public:
		TEXTURE_MANAGER ();
		~TEXTURE_MANAGER ();

		bool build_manually;
		TEXTURE_FILTER used_filter;

//==============================================================================
// Locks or unlocks the next loaded texture's bitmap for user access
//	If locked, the bitmap data is safe from being deleted
//	If unlocked, the bitmap will be deleted immediately after building the texture
//==============================================================================
		void LockTextureBitmap ();
		void UnLockTextureBitmap ();
		bool IsTextureBitmapLocked ();

		H_TEXTURE GetHandle (const std::string &filename);

//==============================================================================
// Gets the texture handle by filename
//
// And loads the texture if needed
//
// Use "G3::Blank" as a filename for an empty texture
// - Needs to be built manually
//==============================================================================
//		H_TEXTURE GetTexture (const string &filename);

//==============================================================================
// Gets a temporary pointer to the texture class
//==============================================================================
//		TEXTURE *GetTexturePointer (H_TEXTURE Handle);

//==============================================================================
// Builds the texture
//==============================================================================
		int BuildTexture2D (H_TEXTURE handle, TEXTURE_FILTER filter = GTF_MIPMAP);

//==============================================================================
// Gets the dimensions of a texture
//==============================================================================
		VEC2I GetTextureDimensions (H_TEXTURE handle);

//==============================================================================
// Gets the bitmap of a recently loaded texture
//
//	NOTE:: 	The texture manager has the right to free texture bitmaps
//			when they are not locked..
//==============================================================================
		boost::shared_ptr<G3::BITMAP> GetTextureBitmap (H_TEXTURE handle);

//==============================================================================
// Gets the identifier (Specific to the renderer) of the texture
//==============================================================================
		uint GetTextureID (H_TEXTURE handle);

//==============================================================================
// Gets the texture flags
//==============================================================================
		uint GetTextureFlags (H_TEXTURE handle);

//==============================================================================
// Applies the texture
//==============================================================================
		void Apply (H_TEXTURE handle);

//==============================================================================
// Gets and applies the texture
//==============================================================================
		void Apply (const char *Filename);

//==============================================================================
// Deletes the texture
//==============================================================================
//		void DeleteTexture (H_TEXTURE Handle);
        void Delete (H_TEXTURE handle);

//==============================================================================
// Dumps the whole texture manager into the log
//==============================================================================
		void Dump ();

		void Clear ();
};

extern TEXTURE_MANAGER TextureManager;

}

#endif
